home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / ACORNUSERS / EMULATOR / MAGICKIT / assembler / c / macro < prev    next >
Text File  |  1998-04-14  |  4KB  |  243 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "defs.h"
  4. #include "externs.h"
  5.  
  6. int   mopt;
  7. int   in_macro;
  8. int   expand_macro;
  9. char  marg[8][10][80];
  10. int   midx;
  11. int   mcounter, mcntmax;
  12. int   mcntstack[8];
  13. struct t_line  *mstack[8];
  14. struct t_line  *mlptr;
  15. struct t_macro *macro_tbl[256];
  16. struct t_macro *mptr;
  17.  
  18. /* .macro pseudo */
  19.  
  20. do_macro(int *ip)
  21. {
  22.     if (pass == LAST_PASS)
  23.         println();
  24.     else {
  25.         if (expand_macro) {
  26.             error("Can not nest macro definitions!");
  27.             return;
  28.         }
  29.         if (lablptr == NULL) {
  30.             error("No name for the macro!");
  31.             return;
  32.         }
  33.         if (!stremove())
  34.             return;
  35.         if (!check_eol(ip))
  36.             return;
  37.         if (!macro_install())
  38.             return;
  39.     } 
  40.     in_macro = 1;
  41. }
  42.  
  43. /* .endm pseudo */
  44.  
  45. do_endm(int *ip)
  46. {
  47.     error("Unexpected ENDM!");
  48.     return;
  49. }
  50.  
  51. /* search for a macro */
  52.  
  53. macro_look(int idx)
  54. {
  55.     char name[32];
  56.     char c;
  57.     int  hash;
  58.     int  i;
  59.  
  60.     i = 0;
  61.     hash = 0;
  62.     while(c = prlnbuf[idx]) {
  63.         if (c == ' ' || c == '\t' || c == ';')
  64.             break;
  65.         if (!isalnum(c) && c != '_')
  66.             return (0);
  67.         if (isdigit(c) && i == 0)
  68.             return (0);
  69.         name[i++] = c;
  70.         hash += c;
  71.         hash = (hash << 3) + (hash >> 5) + c;
  72.         idx++;
  73.         if (i > 31)
  74.             return (0);
  75.     }
  76.  
  77.     name[i] = '\0';
  78.     hash &= 0xFF;
  79.     mptr = macro_tbl[hash];
  80.     while (mptr) {
  81.         if (!strcmp(name, mptr->name))
  82.             break;            
  83.         mptr = mptr->next;
  84.     }
  85.     if (mptr)
  86.         return (macro_extract(idx));
  87.     else
  88.         return (0);
  89. }
  90.  
  91. /* extract macro arguments */
  92.  
  93. macro_extract(int idx)
  94. {
  95.     char *ptr;
  96.     char  c, t;
  97.     int   i, j, f, arg;
  98.  
  99.     if (midx == 7) {
  100.         error("Too many nested macro calls!");
  101.         return (-1);
  102.     }
  103.     mcntstack[midx] = mcounter;
  104.     mstack[midx++] = mlptr;
  105.     arg = 0;
  106.     ptr = marg[midx][0];
  107.     for (i = 0; i < 9; i++) {
  108.        *ptr  = '\0';
  109.         ptr += 80;
  110.     }
  111.     ptr = marg[midx][0];
  112.     for (;;) {
  113.         while (c = prlnbuf[idx]) {
  114.             if (c != ' ' && c != '\t')
  115.                 break;
  116.             idx++;
  117.         }
  118.         switch (c) {
  119.         case ',':
  120.             arg++;
  121.             idx++;
  122.             ptr += 80;
  123.             if (arg == 9) {
  124.                 error("Too many arguments for a macro!");
  125.                 return (-1);
  126.             }
  127.             break;
  128.             
  129.         case '{':
  130.             idx++;
  131.         case '\"':
  132.             i = 0;
  133.             if (c == '{')
  134.                 t = '}';
  135.             else
  136.                 t = '\"';
  137.             while (c = prlnbuf[idx]) {
  138.                 ptr[i++] = c;
  139.                 if (i == 80) {
  140.                     error("Invalid macro argument length!");
  141.                     return (-1);
  142.                 }
  143.                 if (c == t)
  144.                     break;
  145.                 idx++;
  146.             }
  147.             switch (c) {
  148.             case '\0':
  149.                 error("Unterminated ASCII string!");
  150.                 return (-1);
  151.             case '}':
  152.                 i--;
  153.                 break;
  154.             }
  155.             while (c = prlnbuf[++idx]) {
  156.                 if (c != ' ' && c != '\t')
  157.                     break;
  158.             }
  159.             if (c != ',' && c != ';') {
  160.                 error("Syntax error!");
  161.                 return (-1);
  162.             }
  163.             ptr[i] = '\0';
  164.             break;
  165.     
  166.         case ';':
  167.         case '\0':
  168.             return (1);
  169.  
  170.         default:
  171.             i = 0;
  172.             j = 0;
  173.             f = 0;
  174.             while (c = prlnbuf[idx]) {
  175.                 if (c == ',' || c == ';')
  176.                     break;
  177.                 if (f) {
  178.                     if (c != ' ') {
  179.                         for (;i < j; i++)
  180.                             ptr[i++] = ' ';
  181.                         ptr[i++] = c;
  182.                         f = 0;
  183.                     }
  184.                 }
  185.                 else if (c == ' ')
  186.                     f = 1;
  187.                 else 
  188.                     ptr[i++] = c;
  189.                 if (i == 80) {
  190.                     error("Invalid macro argument length!");
  191.                     return (-1);
  192.                 }
  193.                 idx++;
  194.                 j++;
  195.             }
  196.             ptr[i] = '\0';
  197.             break;
  198.         }
  199.     }
  200. }
  201.  
  202. /* install a macro in the hash table */
  203.  
  204. macro_install()
  205. {
  206.     char c;
  207.     int  hash;
  208.     int  i;
  209.  
  210.     hash = 0;
  211.     for (i = 1; i <= symbol[0]; i ++) {
  212.         c = symbol[i];
  213.         if (!isalnum(c) && c != '_') {
  214.             error("Invalid macro name!");
  215.             return (0);
  216.         }
  217.         hash += c;
  218.         hash  = (hash << 3) + (hash >> 5) + c;
  219.     }
  220.     hash &= 0xFF;
  221.     mptr  = macro_tbl[hash];
  222.     while (mptr) {
  223.         if (!strcmp(mptr->name, &symbol[1]))
  224.             break;            
  225.         mptr = mptr->next;
  226.     }
  227.     if (mptr) {
  228.         error("Macro defined twice!");
  229.         return (0);
  230.     }
  231.     if ((mptr = (void *)malloc(sizeof(struct t_macro))) == NULL) {
  232.         error("Out of memory!");
  233.         return (0);
  234.     }
  235.     strcpy(mptr->name, &symbol[1]);
  236.     mptr->line = NULL;
  237.     mptr->next = macro_tbl[hash];
  238.     macro_tbl[hash] = mptr;
  239.     mlptr = NULL;
  240.     return (1);
  241. }
  242.  
  243.